package com.csaba.swing.gui;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.util.Calendar;
import java.util.Date;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import org.jdesktop.swingx.JXDatePicker;

import com.csaba.connector.model.Account;
import com.csaba.connector.model.Bank;
import com.csaba.connector.model.Customer;
import com.csaba.swing.MainWindow;
import com.csaba.swing.gui.util.DynamicColumnLayout;
import com.csaba.swing.model.AccountCache;
import com.csaba.swing.model.BankCache;
import com.csaba.swing.model.CustomerCache;
import com.csaba.swing.model.TransactionFilter;
import com.csaba.util.Formatters;

@SuppressWarnings( "serial" )
public class TransactionFilterDialog extends JDialog
{
	private JComboBox bankCombo;
	private JComboBox customerCombo;
	private JComboBox accountCombo;
	private JXDatePicker from;
	private JXDatePicker to;

	private Date validatedFrom;
	private Date validatedTo;

	private boolean cancelPressed = false;

	private final Bank[] banks;
	private final Customer[] customers;
	private final Account[] accounts;

	private TransactionFilterDialog( final Frame frame )
	{
		super(frame);

		setModal(true);
		setTitle(MainWindow.getString("TransactionFilterDialog.title")); //$NON-NLS-1$
		setResizable(false);

		/*
		 * build buttons, fields, pass values to action.
		 */
		final AbstractAction searchAction = new AbstractAction(MainWindow.getString("TransactionFilterDialog.button.search")) //$NON-NLS-1$
		{
			@Override
			public void actionPerformed( ActionEvent arg0 )
			{
				if ( !validateValues() )
					return;

				cancelPressed = false;
				dispose();
			}
		};
		//create input fields
		final JPanel inputs = new JPanel(new DynamicColumnLayout(new int[] { DynamicColumnLayout.LEFT,
				DynamicColumnLayout.LEFT }));

		inputs.setBorder(BorderFactory.createEmptyBorder());
		inputs.add(new JLabel(MainWindow.getString("TransactionFilterDialog.bank"))); //$NON-NLS-1$
		banks = BankCache.getInstace().getAll(new Bank[0]);
		inputs.add(bankCombo = new JComboBox(banks));
		bankCombo.insertItemAt(MainWindow.getString("TransactionFilterDialog.pleaseSelect"), 0); //$NON-NLS-1$
		bankCombo.setSelectedIndex(0);

		inputs.add(new JLabel(MainWindow.getString("TransactionFilterDialog.customer"))); //$NON-NLS-1$
		customers = CustomerCache.getInstace().getAll(new Customer[0]);
		inputs.add(customerCombo = new JComboBox(customers));
		customerCombo.insertItemAt(MainWindow.getString("TransactionFilterDialog.pleaseSelect"), 0); //$NON-NLS-1$
		customerCombo.setSelectedIndex(0);

		inputs.add(new JLabel(MainWindow.getString("TransactionFilterDialog.account"))); //$NON-NLS-1$
		accounts = AccountCache.getInstace().getAll(new Account[0]);
		inputs.add(accountCombo = new JComboBox(accounts));
		accountCombo.insertItemAt(MainWindow.getString("TransactionFilterDialog.pleaseSelect"), 0); //$NON-NLS-1$
		accountCombo.setSelectedIndex(0);

		//set last anhd next one week as date format
		final Date weekAfter = Calendar.getInstance().getTime();
		final Date oneWeekBefore = Calendar.getInstance().getTime();
		oneWeekBefore.setTime(oneWeekBefore.getTime() - 7L * 24L * 60L * 60L * 1000L);
		weekAfter.setTime(weekAfter.getTime() + 7L * 24L * 60L * 60L * 1000L);
		inputs.add(new JLabel(MainWindow.getString("TransactionFilterDialog.dateFrom"))); //$NON-NLS-1$
		inputs.add(from = new JXDatePicker(oneWeekBefore));
		inputs.add(new JLabel(MainWindow.getString("TransactionFilterDialog.dateTo"))); //$NON-NLS-1$
		inputs.add(to = new JXDatePicker(weekAfter));

		from.setFormats(Formatters.getShortDateFormat());
		to.setFormats(Formatters.getShortDateFormat());

		//create buttons
		final JPanel buttons = new JPanel(new FlowLayout());
		final JButton search = new JButton(searchAction);
		buttons.add(search);

		final JButton cancel = new JButton(new AbstractAction(MainWindow.getString("TransactionFilterDialog.button.cancel")) //$NON-NLS-1$
		{
			@Override
			public void actionPerformed( ActionEvent e )
			{
				cancelPressed = true;
				dispose();
			}

		});
		buttons.add(cancel);

		//create content
		final JPanel content = (JPanel) getContentPane();
		content.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
		content.setLayout(new BorderLayout());
		content.add(inputs, BorderLayout.CENTER);
		content.add(buttons, BorderLayout.SOUTH);

		pack();
		setLocationRelativeTo(frame);
	}

	private boolean validateValues()
	{
		if ( !from.isEditValid() )
		{
			JOptionPane.showMessageDialog(this, MainWindow.getString("TransactionFilterDialog.msg.invalidFromDate"), MainWindow.getString("TransactionFilterDialog.title.error"), JOptionPane.ERROR_MESSAGE); //$NON-NLS-1$ //$NON-NLS-2$
			return false;
		}
		if ( !to.isEditValid() )
		{
			JOptionPane.showMessageDialog(this, MainWindow.getString("TransactionFilterDialog.msg.invalidToDate"), MainWindow.getString("TransactionFilterDialog.title.error"), JOptionPane.ERROR_MESSAGE); //$NON-NLS-1$ //$NON-NLS-2$
			return false;
		}
		validatedFrom = from.getDate();
		validatedTo = to.getDate();

		if ( validatedFrom.after(validatedTo) )
		{
			JOptionPane.showMessageDialog(this, MainWindow.getString("TransactionFilterDialog.msg.invalidRange"), MainWindow.getString("TransactionFilterDialog.title.error"), //$NON-NLS-1$ //$NON-NLS-2$
					JOptionPane.ERROR_MESSAGE);
			return false;
		}

		return true;
	}

	public static TransactionFilter getFilter( final TransactionFilter oldValues )
	{
		final TransactionFilterDialog dialog = new TransactionFilterDialog(MainWindow.getFrame());

		if ( oldValues != null )
		{
			dialog.bankCombo.setSelectedItem(oldValues.getBank());
			dialog.customerCombo.setSelectedItem(oldValues.getCustomer());
			dialog.accountCombo.setSelectedItem(oldValues.getAccount());

			dialog.from.setDate(oldValues.getFrom());
			dialog.to.setDate(oldValues.getTo());
		}
		dialog.setVisible(true);

		if ( dialog.cancelPressed )
		{
			return null;
		}

		final TransactionFilter result = new TransactionFilter();

		if ( dialog.bankCombo.getSelectedIndex() > 0 )
			result.setBank((Bank) dialog.bankCombo.getSelectedItem());
		if ( dialog.customerCombo.getSelectedIndex() > 0 )
			result.setCustomer((Customer) dialog.customerCombo.getSelectedItem());
		if ( dialog.accountCombo.getSelectedIndex() > 0 )
			result.setAccount((Account) dialog.accountCombo.getSelectedItem());

		result.setFrom(dialog.validatedFrom);
		result.setTo(dialog.validatedTo);

		return result;
	}
}
